package remote.controls
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import remote.collections.IList;
	import remote.containers.Container;
	import remote.containers.VGroup;
	import remote.core.IMultiSelect;
	import remote.skins.SolidRectangleSkin;
	
	[Event(name="change", type="flash.events.Event")]
	/**
	 * 列表
	 * @author 银魂飞雪
	 * @createDate 2011-4-24
	 */
	public class List extends Scroller implements IList
	{
		private var _content:Container;
		private var _dataProvider:IList;
		private var _itemRender:Class = DefaultListItemRender;
		private var _selectedIndexs:Array;
		
		private var _rowHeight:Number = -1;
		private var _rowWidth:Number = NaN;			
		private var _allowMulSelected:Boolean = true;
		public function List()
		{
			super();
			_selectedIndexs = new Array();
			this.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
		}

		private function downHandler(e:MouseEvent):void
		{
			var target:IListItemRender = e.target as IListItemRender;
			if(target != null)
			{
				var targetIndex:int = _dataProvider.getItemIndex(target.data);
				if(!_allowMulSelected)
				{
					if(_selectedIndexs.length > 1 || selectedIndex != targetIndex)
					{
						clearSelected();
						select(targetIndex);
						dispatchEvent(new Event(Event.CHANGE));
					}
				}
				else
				{
					if(e.ctrlKey)
					{
						if(!target.selected)
						{
							select(targetIndex);
							dispatchEvent(new Event(Event.CHANGE));
						}
					}
					else if(e.shiftKey)
					{
						var startIndex:int = Math.min(targetIndex, selectedIndex), endIndex:int = Math.max(targetIndex, selectedIndex) + 1;
						select(startIndex, endIndex);
						dispatchEvent(new Event(Event.CHANGE));
					}
					else
					{
						if(_selectedIndexs.length > 1 || selectedIndex != targetIndex)
						{
							clearSelected();
							select(targetIndex);
							dispatchEvent(new Event(Event.CHANGE));
						}
					}
				}
			}
		}
		
		
		public function get length():int
		{
			return _dataProvider.length;
		}
		
		public function addItem(item:Object):void
		{
			_dataProvider.addItem(item);
			var render:IListItemRender = createItemRender(item);
			content.addChild(render as DisplayObject);
		}
		
		public function removeItem(item:Object):Object
		{
			var index:int = this.getItemIndex(item);
			if(index >= 0)
			{
				return removeItemAt(index);
			}
			return null;
		}
		
		public function addItemAt(item:Object, index:int):void
		{
			_dataProvider.addItemAt(item, index);
			content.addChildAt(createItemRender(item) as DisplayObject, index);
			for(var i:int = 0; i < _selectedIndexs.length; i++)
			{
				if(_selectedIndexs[i] >= index)
					_selectedIndexs[i]++;
			}
		}
		
		public function removeItemAt(index:int):Object
		{
			_dataProvider.removeItemAt(index);
			for(var i:int = 0; i < _selectedIndexs.length; i++)
			{
				if(_selectedIndexs[i] == index)
					_selectedIndexs.splice(i--, 1);
				else if(_selectedIndexs[i] > index)
					_selectedIndexs[i]--;
			}
			return content.removeChildAt(index);
		}
		
		public function getItemAt(index:int):Object
		{
			return _dataProvider.getItemAt(index);
		}
		
		public function getItemIndex(item:Object):int
		{
			return _dataProvider.getItemIndex(item);	
		}
		
		public function removeAll():void
		{
			_dataProvider.removeAll();
			content.removeAllChildren();
		}
		
		public function setItemAt(item:Object, index:int):Object
		{
			content.setChildIndex(itemToRender(item) as DisplayObject, index);
			return _dataProvider.setItemAt(item, index);
		}
		
		public function toArray():Array
		{
			return _dataProvider.toArray();
		}
		override protected function createSkin():void
		{
			_skin = new SolidRectangleSkin();
		}
		
		/**
		 * 设置选中项
		 * <p>如果只选中一项，无需设置endIndex</p> 
		 * @param startIndex 选中的起始项，包含此项
		 * @param endIndex 选中的结束项,不包含此项
		 * 
		 */		
		public function select(startIndex:int, endIndex:int = -1):void
		{
			if(startIndex < 0)
				startIndex = 0;
			if(endIndex == -1)
				endIndex = startIndex + 1;
			else if(endIndex > _dataProvider.length)
				endIndex = _dataProvider.length;
			for(var i:int = startIndex; i < endIndex; i++)
			{
				if(_selectedIndexs.indexOf(i) == -1)
				{
					_selectedIndexs.push(i);
					indexToRender(i).selected = true;
				}
			}
		}
		
		/**
		 * 清空选中项 
		 * 
		 */		
		public function clearSelected():void
		{
			for each(var index:int in _selectedIndexs)
			{
				(content.getChildAt(index) as IListItemRender).selected = false;
			}
			_selectedIndexs.splice(0);
		}
		
		/**
		 * 刷新所有项 
		 * 
		 */		
		public function refresh():void
		{
			content.removeAllChildren();
			for(var i:int = 0; i < _dataProvider.length; i++)
			{
				content.addChild(createItemRender(_dataProvider.getItemAt(i)) as DisplayObject);
			}
		}
		
		/**
		 * 更新一项的显示
		 * @param index 序号
		 * 
		 */		
		public function updateIndex(index:int):void
		{
			indexToRender(index).update();
		}

		/**
		 *  
		 * @param item
		 * 
		 */		
		public function updateItem(item:Object):void
		{
			for(var i:int = 0; i < length; i++)
			{
				if(_dataProvider.getItemAt(i) == item)
					indexToRender(i).update();
			}
		}
		
		private function updateItemRenderSize():void
		{
			for(var i:int = 0; i < content.numChildren; i++)
			{
				setItemRenderSize(content.getChildAt(i));
			}
		}
		
		private function setItemRenderSize(render:DisplayObject):void
		{
			if(isNaN(_rowWidth))
				render.width = width - layout.edge.left - layout.edge.right;
			else if(_rowWidth >= 0)
				render.width = _rowWidth;
			if(_rowHeight >= 0)
				render.height = _rowHeight;
		}
		
		/**
		 * 通过坐标点获取列表项 
		 * @param x 水平坐标
		 * @param y 竖直坐标
		 * @return  列表项
		 * 
		 */		
		public function positionToRender(x:Number, y:Number):IListItemRender
		{
			var positionForContent:Point = new Point(x - content.x, y - content.y);
			if(positionForContent.x > 0 && positionForContent.y > 0 
				&& positionForContent.x < content.width && positionForContent.y < content.height)
			{
				var h:Number = 0;
				for(var i:int = 0; i < content.numChildren; i++)
				{
					var child:DisplayObject = content.getChildAt(i);
					h += child.height;
					if(positionForContent.x >= child.x && positionForContent.y >= child.y &&  positionForContent.y <= (child.y + child.height))
						return child as IListItemRender;
					h += (content as VGroup).gap;
					if(h > positionForContent.y)
						return null;
				}
			}
			return null;
		}
		
		/**
		 * 通过数据获取列表项 
		 * @param item 数据项
		 * @return 列表项
		 * 
		 */		
		public function itemToRender(item:Object):IListItemRender
		{
			var index:int = _dataProvider.getItemIndex(item);
			if(index != -1)
				return content.getChildAt(index) as IListItemRender;
			return null;
		}
		
		private function getRenderByItem(item:Object):IListItemRender
		{
			for(var i:int = 0; i < _content.numChildren; i++)
			{
				var render:IListItemRender = _content.getChildAt(i) as IListItemRender;
				if(render.data == item)
					return render;
			}
			return null;
		}
		/**
		 * 通过序号获取列表项 
		 * @param index 序号
		 * @return 列表项
		 * 
		 */		
		public function indexToRender(index:int):IListItemRender
		{
			return _content.getChildAt(index) as IListItemRender;
		}
		private function createItemRender(data:Object):IListItemRender
		{
			var render:IListItemRender = new _itemRender() as IListItemRender;
			render.data = data;
			setItemRenderSize(render as DisplayObject);
			return render;
		}
		
		override protected function createChildren():void
		{
			super.createChildren();
			_content = new VGroup();
			content = _content;
		}

		/**
		 * 控件的自定义项目渲染器 
		 * 
		 */		
		public function get itemRender():Class
		{
			return _itemRender;
		}

		public function set itemRender(value:Class):void
		{
			if(_itemRender != value)
			{
				_itemRender = value;
				this.refresh();
			}
		}

		/**
		 * 数据源 
		 * 
		 */		
		public function get dataProvider():IList
		{
			return _dataProvider;
		}

		public function set dataProvider(value:IList):void
		{
			if(_dataProvider != value)
			{
				_dataProvider = value;
				this.refresh();
			}
				
		}

		/**
		 * 行宽
		 * <p>-1表示自适应</p>
		 * <p>NaN表示和组件宽度相同</p>
		 * 
		 */	
		public function get rowWidth():Number
		{
			return _rowWidth;
		}

		public function set rowWidth(value:Number):void
		{
			if(_rowWidth != value)
			{
				_rowWidth = value;
				updateItemRenderSize();
			}
		}

		/**
		 * 行高
		 * <p>-1表示自适应值</p> 
		 * 
		 */	
		public function get rowHeight():Number
		{
			return _rowHeight;
		}

		public function set rowHeight(value:Number):void
		{
			if(_rowHeight != value)
			{
				_rowHeight = value;
				updateItemRenderSize();
			}
		}
		
		/**
		 * 选中项序号。
		 * <p>处于单选状态时，此值表示当前选中的序号</p>
		 * <p>处于多选状态时，此值表示最后选中的项的序号</p>
		 * 
		 */		
		public function get selectedIndex():int
		{
			if(_selectedIndexs.length > 0)
			{
				return _selectedIndexs[_selectedIndexs.length - 1];
			}
			return -1;
		}

		/**
		 * 选中项 
		 * 
		 */		
		public function get selectedItem():Object
		{
			return _dataProvider.getItemAt(selectedIndex);
		}
		
		/**
		 * 选中项序号集合 
		 * 
		 */		
		public function get selectedIndexs():Array
		{
			return _selectedIndexs;
		}

		public function set selectedIndexs(value:Array):void
		{
			clearSelected();
			for each(var index:int in value)
			{
				select(index);
			}
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		/**
		 * 选中项集合 
		 * @return 
		 * 
		 */		
		public function get selectedItems():Array
		{
			var result:Array = [];
			for(var i:int = 0; i < _selectedIndexs.length; i++)
			{
				result.push(_dataProvider.getItemAt(_selectedIndexs[i]));
			}
			return result;
		}


	}
}